﻿using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.IdentityModel.Tokens;
using TokenApi.Contract;
using TokenApi.Contract.Domain;
using TokenApi.Service.Contract;
using TokenApi.Service.Infrastructure;
using TokenApi.Service.Options;

namespace TokenApi.Service.Service;

public sealed class OpenAIService(IHttpClientFactory httpClientFactory) : IChatService
{
    public const string Name = nameof(OpenAIService);

    public async IAsyncEnumerable<CompletionResult> CompletionsAsync<T>(ChatCompletionDto<T>? dto,
        ChatChannel data = null)
    {
        var httpClient = httpClientFactory.CreateClient(Name);
        using var response = await httpClient?.HttpRequestRaw(
            OpenAIOptions.Endpoint.TrimEnd('/') + "/v1/chat/completions", dto,
            OpenAIOptions.ApiKey);

        if (dto?.model != "gpt-4-vision-preview")
        {
            const string prefix = "data: ";
            var reader = new StreamReader(await response.Content.ReadAsStreamAsync());
            // 消息队列
            while (await reader.ReadLineAsync() is { } line)
            {
                var idx = line.IndexOf(prefix, StringComparison.Ordinal);
                if (idx == -1)
                {
                    continue;
                }

                var d = line[prefix.Length..];
                if (d == "[DONE]")
                {
                    continue;
                }

                var res = JsonSerializer.Deserialize<OpenAIResult>(d, new JsonSerializerOptions()
                {
                    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
                });
                var content = res?.choices.FirstOrDefault()?.delta?.content;

                if (content.IsNullOrEmpty()) continue;

                yield return new CompletionResult(content);
            }
        }
    }
}